﻿using Intersoft.Crosslight;
using Intersoft.Crosslight.Mobile;
using OvenParameterForm.CustomizeControl;
using OvenParameterForm.Device;
using OvenParameterForm.Model;
using OvenParameterForm.Panel;
using OvenParameterForm.Technics;
using OvenParameterForm.Util;
using SqlSugar;
using Sunny.UI;
using Sunny.UI.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Xml.Linq;

namespace OvenParameterForm
{
    public partial class Frm_Oven : UIForm
    {
        List<NumericUpDown> nudlist = new List<NumericUpDown>();
        string formulaPath = Application.StartupPath + "\\配方文件\\";
        event EventHandler CheckParameterEvent;
        SqlSugarClientHelp<OvenAndFormula> clientHelp = new SqlSugarClientHelp<OvenAndFormula>();
        /// <summary>
        /// //增加控件指向提示属性
        /// </summary>
        protected ToolTip tooltip = new ToolTip();
        public static Frm_Oven Instance = new Frm_Oven();
        public static Frm_Oven GetInstance() { return Instance; }
        public Frm_Oven()
        {
            InitializeComponent();
            nudlist.AddRange(gbox_settingParameter.Controls.OfType<NumericUpDown>());//{抽充次数,抽气设定值,充气设定值,加热设定温度,超温报警值,超温停机值,降温报警值,工艺时间}
            CheckParameterEvent += (sender, e) =>
            {
                MessageBox.Show("支线时间和不能大于保温时间", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                // UIMessageBox.ShowError("支线时间和不能大于保温时间");
            };
            btn_changeTechnics.Enabled = false;
            tooltip.SetToolTip(this.btn_ovenLoadFormula, "更换所选择烘箱配方，相当于更改烘箱与配方的绑定关系");
        }
        /// <summary>
        /// 检查气氛工艺参数是否正确，首先值不能为0，其次温度报警值相互有限制范围
        /// </summary>
        /// <returns></returns>
        private bool ParameterCheck()
        {
            var v = nudlist.FirstOrDefault(f => f.Enabled && f.Value == 0);
            if (v != null)
            {
                MessageBox.Show($"{v.Tag}不能为0", "参数设定错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            else if ((nud_settingHot.Enabled) && (nud_alarmValueOfHighTemperture.Value <= nud_settingHot.Value || nud_alarmValueOfLowTemperture.Value >= nud_settingHot.Value ||
        nud_stopValueOfHighTemperture.Value <= nud_alarmValueOfHighTemperture.Value))
            {
                MessageBox.Show($"温度参数值必须符合以下条件：\r 1:降温报警值<加热温度设定值<超温报警值\r 2:超温停机值>超温报警值", "参数设定错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            else
            { return true; }

        }
        /// <summary>
        /// 添加单步工艺
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_addTechincs_Click(object sender, EventArgs e)
        {
            if (ParameterCheck())
            {
                string str = CreatNodeText(cmb_choseTechnics.Text);
                if (tv_ovenTechnologicalProcess.SelectedNode != null)
                {
                    int c = PublicFunc.BoolArrayGetValue(new bool[] {
                            tv_ovenTechnologicalProcess.SelectedNode.Level == 0,//选择是否是主线
                                        cmb_choseNode.SelectedIndex == 0//插入是否是主线            
                });
                    switch (c)
                    {
                        case 0://支线后插支线
                            if (!CheckNewParameterInfo(tv_ovenTechnologicalProcess.SelectedNode, str))
                            {
                                CheckParameterEvent(null, null);
                                return;
                            }
                            tv_ovenTechnologicalProcess.SelectedNode.Parent.Nodes.Insert(
                          tv_ovenTechnologicalProcess.SelectedNode.Index + 1, str);
                            break;
                        case 1://支线后插主线
                            int index = tv_ovenTechnologicalProcess.Nodes.IndexOf(tv_ovenTechnologicalProcess.SelectedNode.Parent);
                            tv_ovenTechnologicalProcess.Nodes.Insert(index + 1, str);
                            break;
                        case 2://主线后插支线
                            if (tv_ovenTechnologicalProcess.SelectedNode.Text.SplitFirst(",").Equals("保温"))
                            {
                                if (!CheckNewParameterInfo(tv_ovenTechnologicalProcess.SelectedNode, str))
                                {
                                    CheckParameterEvent(null, null);
                                    return;
                                }
                                if (tv_ovenTechnologicalProcess.SelectedNode.Nodes.Count < 1)
                                {
                                    tv_ovenTechnologicalProcess.SelectedNode.Nodes.Add(str);
                                }
                                else
                                {
                                    tv_ovenTechnologicalProcess.SelectedNode.Nodes.Insert(0, str);
                                }
                            }
                            else
                            {
                                MessageBox.Show("支节点无法插入非保温下的主节点，请选择正确的主节点", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            }
                            break;
                        case 3://主线后插主线
                            tv_ovenTechnologicalProcess.Nodes.Insert(tv_ovenTechnologicalProcess.SelectedNode.Index + 1, str);
                            break;
                    }
                }
                else//没有选择，直接在最后一道工艺后面添加工艺
                {
                    if (cmb_choseNode.SelectedIndex == 0)
                    {
                        tv_ovenTechnologicalProcess.Nodes.Add(str);
                    }
                    else
                    {
                        tv_ovenTechnologicalProcess.Nodes[tv_ovenTechnologicalProcess.Nodes.Count - 1].Nodes.Add(str);
                    }
                }
                #region if多层嵌套
                //if (tv_ovenTechnologicalProcess.SelectedNode != null)
                //{
                //    if (tv_ovenTechnologicalProcess.SelectedNode.Level == 0)//从主节点下插入
                //    {
                //        if (cmb_choseNode.SelectedIndex == 0)//主节点插入主节点
                //        {
                //            tv_ovenTechnologicalProcess.Nodes.Insert(tv_ovenTechnologicalProcess.SelectedNode.Index + 1, str);
                //        }
                //        else//主节点插入支节点
                //        {
                //            if (tv_ovenTechnologicalProcess.SelectedNode.Text.SplitFirst(",").Equals("保温"))
                //            {
                //                if (!CheckNewParameterInfo(tv_ovenTechnologicalProcess.SelectedNode, str))
                //                {
                //                    CheckParameterEvent(null, null);
                //                    return;
                //                }
                //                if (tv_ovenTechnologicalProcess.SelectedNode.Nodes.Count < 1)
                //                {
                //                    tv_ovenTechnologicalProcess.SelectedNode.Nodes.Add(str);
                //                }
                //                else
                //                {
                //                    tv_ovenTechnologicalProcess.SelectedNode.Nodes.Insert(0, str);
                //                }
                //            }
                //            else
                //            {
                //                MessageBox.Show("支节点无法插入非保温下的主节点，请选择正确的主节点", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                //            }
                //        }
                //    }
                //    else//从支节点下插入
                //    {
                //        if (cmb_choseNode.SelectedIndex == 0)//支节点下插入主节点
                //        {
                //            int index = tv_ovenTechnologicalProcess.Nodes.IndexOf(tv_ovenTechnologicalProcess.SelectedNode.Parent);
                //            tv_ovenTechnologicalProcess.Nodes.Insert(index + 1, str);
                //        }
                //        else//支节点下插入支节点
                //        {
                //            if (!CheckNewParameterInfo(tv_ovenTechnologicalProcess.SelectedNode, str))
                //            {
                //                CheckParameterEvent(null, null);
                //                return;
                //            }
                //            tv_ovenTechnologicalProcess.SelectedNode.Parent.Nodes.Insert(
                //          tv_ovenTechnologicalProcess.SelectedNode.Index + 1, str);
                //        }
                //    }
                //}
                //else//没有选择，直接在最后一道工艺后面添加工艺
                //{
                //    if (cmb_choseNode.SelectedIndex == 0)
                //    {
                //        tv_ovenTechnologicalProcess.Nodes.Add(str);
                //    }
                //    else
                //    {
                //        tv_ovenTechnologicalProcess.Nodes[tv_ovenTechnologicalProcess.Nodes.Count - 1].Nodes.Add(str);
                //    }
                //}
                #endregion

                tv_ovenTechnologicalProcess.ExpandAll();
            }
        }
        /// <summary>
        /// 创建节点信息
        /// </summary>
        /// <param name="technics"></param>
        /// <returns></returns>
        private string CreatNodeText(string technics)
        {
            nudlist.ForEach(f =>
            {
                if (f.Enabled) { technics = technics + "," + f.Value.ToString(); }
            });
            return technics;
        }
        /// <summary>
        /// 插入或修改支线信息时需要检查时间是否超过主线保温状态的总时间
        /// </summary>
        /// <param name="parentTn">所选择的TreeNode</param>
        /// <param name="newPara">插入新参数，即要检验的参数</param>
        /// <param name="bchange">是否是改参数，</param>
        /// <returns></returns>
        private bool CheckNewParameterInfo(TreeNode parentTn, string newPara, bool bchange = false)
        {
            int level = parentTn.Level;
            int newTime = int.Parse(newPara.SplitLast(",").Trim());//新参数时间
            int tempSumTime = 0;
            int maxTime = int.Parse((level.Equals(0) ? parentTn : parentTn.Parent).Text.SplitLast(",").Trim()); ;//总保温时间
            if (bchange)//修改检查
            {
                TreeNode changeTreeNode = level.Equals(0) ? parentTn : parentTn.Parent;
                if (changeTreeNode.Nodes.Count > 0)//如果总保温下面已经有支线了，需要计算下已有参数时间和
                {
                    for (int i = 0; i < changeTreeNode.Nodes.Count; i++)
                    {
                        if (level.Equals(0))
                        {
                            tempSumTime += int.Parse(changeTreeNode.Nodes[i].Text.SplitLast(",").Trim());
                        }
                        else
                        {
                            tempSumTime += i != parentTn.Index ? int.Parse(changeTreeNode.Nodes[i].Text.SplitLast(",").Trim()) : newTime;
                        }
                    }
                    return level.Equals(0) ? newTime > tempSumTime : maxTime > tempSumTime;
                }
                else//如果总保温下面没支线，则新时间就是临时总时间
                {
                    return true;
                }
            }
            else//插入检查
            {
                TreeNode insertTreeNode = level.Equals(0) ? parentTn : parentTn.Parent;
                if (insertTreeNode.Nodes.Count > 0)//如果总保温下面已经有支线了，需要计算下已有参数时间和
                {
                    for (int i = 0; i < insertTreeNode.Nodes.Count; i++)
                    {
                        tempSumTime += int.Parse(insertTreeNode.Nodes[i].Text.SplitLast(",").Trim());
                    }
                    tempSumTime = tempSumTime + newTime;
                }
                else//如果总保温下面没支线，则新时间就是临时总时间
                {
                    tempSumTime = newTime;
                }
                return maxTime >= tempSumTime;
            }

        }
        /// <summary>
        /// 界面加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            cmb_choseTechnicsInitialize();
            cmb_choseNode.SelectedIndex = 0;
            cmb_ovenChose.SelectedIndex = 0;
            UpdateDgv_ovenAndFormula();//初始化全加载刷新
            var v = PLC.open();
            if (!v)
            {
                MessageBox.Show("PLC未连接上,请检查", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
        }
        /// <summary>
        /// 选择工艺控件初始化
        /// </summary>
        private void cmb_choseTechnicsInitialize(bool main = true)
        {
            cmb_choseTechnics.Items.Clear();
            if (main)
            {
                cmb_choseTechnics.Items.AddRange(new object[] {
            "抽充","加热","保温","抽真空","小补气"
            });
            }
            else
            {
                cmb_choseTechnics.Items.AddRange(new object[] {
            "抽真空","小补气"
            });
            }

            cmb_choseTechnics.SelectedIndex = 0;
        }
        /// <summary>
        /// 选择工艺
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmb_choseTechnics_SelectedIndexChanged(object sender, EventArgs e)
        {
            nudlist.ForEach(n => { n.Enabled = false; });
            switch (cmb_choseTechnics.Text)
            {
                case "抽充":
                    nud_timesOfVacuumAndAirInflation.Enabled = true;
                    nud_settingVacuum.Enabled = true;
                    nud_settingAirInflation.Enabled = true;
                    break;
                case "加热":
                    nud_settingHot.Enabled = true;
                    nud_alarmValueOfHighTemperture.Enabled = true;
                    nud_alarmValueOfLowTemperture.Enabled = true;
                    nud_stopValueOfHighTemperture.Enabled = true;
                    break;
                case "保温":
                    nud_timeOfThechnics.Enabled = true;
                    break;
                case "抽真空":
                    nud_settingVacuum.Enabled = true;
                    nud_timeOfThechnics.Enabled = true;
                    break;
                case "小补气":
                    nud_settingAirInflation.Enabled = true;
                    nud_timeOfThechnics.Enabled = true;
                    break;

            }
        }
        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_deleteTechnics_Click(object sender, EventArgs e)
        {
            if (tv_ovenTechnologicalProcess.SelectedNode == null)
            {
                MessageBox.Show("请选择要删除的工艺节点!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            System.Windows.Forms.DialogResult dr = MessageBox.Show("确定要删除该节点吗", "确认信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                tv_ovenTechnologicalProcess.SelectedNode.Remove();
                tv_ovenTechnologicalProcess.SelectedNode = null;
                btn_changeTechnics.Enabled = false;
            }
        }
        /// <summary>
        /// 选择节点类型
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmb_choseNode_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmb_choseTechnicsInitialize(cmb_choseNode.SelectedIndex == 0);
        }
        /// <summary>
        /// 树视图选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_ovenTechnologicalProcess_AfterSelect(object sender, TreeViewEventArgs e)
        {

            cmb_choseNode.SelectedIndex = tv_ovenTechnologicalProcess.SelectedNode.Level;
            string[] arrayStr = tv_ovenTechnologicalProcess.SelectedNode?.ToString().Split(':')[1].Split(',');
            cmb_choseTechnics.Text = arrayStr[0].Trim();
            var v = nudlist.Where(w => w.Enabled);
            for (int i = 0; i < v.Count(); i++)
            {
                v.ToArray()[i].Value = decimal.Parse(arrayStr[i + 1]);
            }
            btn_changeTechnics.Enabled = true;
        }
        /// <summary>
        /// 改变工艺参数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_changeTechnics_Click(object sender, EventArgs e)
        {
            if (tv_ovenTechnologicalProcess.SelectedNode != null && ParameterCheck())
            {
                string newstr = CreatNodeText(cmb_choseTechnics.Text);
                if (tv_ovenTechnologicalProcess.SelectedNode.Level == 0)//如果选择是主线
                {
                    string oldstr = tv_ovenTechnologicalProcess.SelectedNode.Text.SplitFirst(",").Trim();
                    if (oldstr.Equals("保温") & newstr.SplitFirst(",").Equals("保温") & !CheckNewParameterInfo(tv_ovenTechnologicalProcess.SelectedNode, newstr, true))
                    {
                        CheckParameterEvent(null, null);
                        return;
                    }
                    if (oldstr.Equals("保温") & tv_ovenTechnologicalProcess.SelectedNode.Nodes.Count > 0 & !newstr.SplitFirst(",").Equals("保温"))
                    {
                        MessageBox.Show("保温主线下有支线，无法直接替换其他工艺，请先删除支线再修改", "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                    tv_ovenTechnologicalProcess.SelectedNode.Text = newstr;
                }
                else//如果选择的是支线
                {
                    if (!CheckNewParameterInfo(tv_ovenTechnologicalProcess.SelectedNode, newstr, true))
                    {
                        CheckParameterEvent(null, null);
                    }
                    else
                    {
                        tv_ovenTechnologicalProcess.SelectedNode.Text = newstr;
                    }
                }

            }
        }
        /// <summary>
        /// 保存工艺配方，将treeNode先生成对应类，再用类转XML
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_saveFormula_Click(object sender, EventArgs e)
        {
            XDocument xdoc = new XDocument();
            xdoc.Add(new XElement("工艺配方"));
            XElement TreeNodeToXML(TreeNode tn)
            {
                string[] strArray = tn.Text.Split(",");
                TechnicsBaseClass temp = (TechnicsBaseClass)Assembly.GetExecutingAssembly().CreateInstance("OvenParameterForm.Technics." + strArray[0], true, BindingFlags.Default, null, new object[] { strArray }, null, null);
                return PublicFunc.ClassToXML(temp);
            }
            foreach (TreeNode item in tv_ovenTechnologicalProcess.Nodes)
            {
                if (item.Text.SplitFirst(",").Equals("保温"))
                {
                    XElement xtemp = TreeNodeToXML(item);
                    foreach (TreeNode childItem in item.Nodes)
                    {
                        xtemp.Add(TreeNodeToXML(childItem));
                    }
                    xdoc.Root.Add(xtemp);
                }
                else
                {
                    xdoc.Root.Add(TreeNodeToXML(item));
                }
            }
            if (!Directory.Exists(formulaPath)) Directory.CreateDirectory(formulaPath);
            xdoc.Save(formulaPath + tbox_formulaName.Text.Trim() + ".xml");
        }
        /// <summary>
        /// 打开工艺配方
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_openFormula_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = formulaPath;
            ofd.Filter = "烘箱气氛工艺流程(*.xml)|*.xml";
            ofd.Multiselect = false;
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                tbox_formulaName.Text = ofd.FileName.SplitLast("\\").SplitFirst(".");
                OpenFormula(ofd.FileName);
            }
        }
        /// <summary>
        /// 打开配方，历遍XML文档，添加相关参数，如果有子支线，再次历遍
        /// </summary>
        /// <param name="path"></param>
        private void OpenFormula(string path)
        {
            try
            {
                XDocument xdoc = XDocument.Load(path);
                tv_ovenTechnologicalProcess.Nodes.Clear();
                xdoc.Root.Elements().ForEach(f =>
                {
                    tv_ovenTechnologicalProcess.Nodes.Add(XMLToTreeNodeInfo(f));
                    if (f.HasElements)
                    {
                        f.Elements().ForEach(b =>
                        {
                            tv_ovenTechnologicalProcess.Nodes[tv_ovenTechnologicalProcess.Nodes.Count - 1].Nodes.Add(XMLToTreeNodeInfo(b));
                        });
                    }
                });
                tv_ovenTechnologicalProcess.ShowPlusMinus = false;
                tv_ovenTechnologicalProcess.ExpandAll();
            }
            catch
            {

            }

            string XMLToTreeNodeInfo(XElement xl)
            {
                string tempStr = xl.Name.ToString();
                xl.Attributes().ForEach(a => { tempStr += "," + a.Value; });
                return tempStr;
            }
        }
        /// <summary>
        /// 添加烘箱
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_addOven_Click(object sender, EventArgs e)
        {
            Frm_ovenSetting fos = new Frm_ovenSetting();
            string name = "";
            fos.sendOvenName = (string str) => { name = str; };
            fos.ShowDialog();
            clientHelp.InsertData(new Model.OvenAndFormula()
            {
                OvenName = name,
                FormulaName = tbox_formulaName.Text,
                LoadTime = DateTime.Now,
                FormulaPath = formulaPath + tbox_formulaName.Text + ".xml"
            });
            UpdateDgv_ovenAndFormula(1, name);//增加刷新
        }
        /// <summary>
        /// 删除烘箱
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_delelteOven_Click(object sender, EventArgs e)
        {
            if (!CheckOvenState(dgv_ovenAndFormula.SelectedRows[0].Cells[1].Value.ToString()))
            {
                MessageBox.Show($"{dgv_ovenAndFormula.SelectedRows[0].Cells[1].Value.ToString()}正在运行中，无法删除烘箱，请先停止烘箱工艺再加载新配方", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if (dgv_ovenAndFormula.SelectedRows.Count == 0) return;
            OvenAndFormula t = new OvenAndFormula();
            clientHelp.FindFirstByCondition(dgv_ovenAndFormula.SelectedRows[0].Cells[1].Value.ToString(), "OvenName", out t);
            clientHelp.DeleteData(t);
            UpdateDgv_ovenAndFormula(2, dgv_ovenAndFormula.SelectedRows[0].Cells[1].Value.ToString());//删除刷新


        }
        /// <summary>
        /// 给烘箱加载选择的配方，更换烘箱的配方
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ovenLoadFormula_Click(object sender, EventArgs e)
        {
            if (cmb_ovenChose.Text.Trim().Equals("") || tbox_formulaName.Text.Trim().Equals("")) return;
            if (!CheckOvenState(cmb_ovenChose.Text.Trim()))
            {
                MessageBox.Show($"{cmb_ovenChose.Text.Trim()}正在运行中，无法加载新配方，请先停止烘箱工艺再加载新配方", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            OvenAndFormula t = new OvenAndFormula();
            clientHelp.FindFirstByCondition(cmb_ovenChose.Text, "OvenName", out t);//根据烘箱名称查找相关信息
            t.FormulaName = tbox_formulaName.Text.Trim();//修改烘箱与配方的绑定信息
            t.FormulaPath = formulaPath + tbox_formulaName.Text + ".xml";
            clientHelp.UpdateData(t);
            UpdateDgv_ovenAndFormula(3, cmb_ovenChose.Text.Trim());//加载配方刷新

        }
        /// <summary>
        /// 更新烘箱和配方,只要烘箱数量发生变化就更新,画面加载，添加烘箱，删除烘箱，加载配方
        /// </summary>
        /// <param name="ovenQuantity">烘箱数量变化标志，0是清空刷新，1是增加刷新，2是删除刷新，3是刷新</param>
        /// <param name="name">烘箱名称，默认为空</param>
        private void UpdateDgv_ovenAndFormula(int ovenQuantity = 0, string name = null)
        {
            dgv_ovenAndFormula.DataSource = null;
            List<OvenAndFormula> of = clientHelp.QueryAll();
            dgv_ovenAndFormula.DataSource = of;
            dgv_ovenAndFormula.Columns[0].HeaderText = "ID";
            dgv_ovenAndFormula.Columns[0].Visible = false;
            dgv_ovenAndFormula.Columns[1].HeaderText = "烘箱名称";
            dgv_ovenAndFormula.Columns[2].HeaderText = "配方名称";
            dgv_ovenAndFormula.Columns[3].HeaderText = "加载日期";
            dgv_ovenAndFormula.Columns[3].DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss";
            dgv_ovenAndFormula.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            dgv_ovenAndFormula.Columns[4].Visible = false;

            switch (ovenQuantity)
            {
                case 0://清空，全加载
                    if (tc_ovenProcessList.Controls.Count > 0) tc_ovenProcessList.Controls.Clear();
                    if (tc_ovenHistoryList.Controls.Count > 0) tc_ovenHistoryList.Controls.Clear();
                    cmb_ovenChose.Items.Clear();
                    of.ForEach(o =>
                    {
                        cmb_ovenChose.Items.Add(o.OvenName);
                        Tc_OvenRun t1 = new Tc_OvenRun(o.OvenName);
                        Tc_OvenHistoryChart t2 = new Tc_OvenHistoryChart(o.OvenName);
                        AddOvenTabpage(t1, o.OvenName, tc_ovenProcessList);
                        AddOvenTabpage(t2, o.OvenName, tc_ovenHistoryList);
                        t1.oven.technicsOverAction += () => {

                            if (t2.InvokeRequired)
                            {
                                t2.Invoke(new Action(() => { t2.LoadPage(); }));
                            }
                            else
                            {
                                t2.LoadPage();
                            }                        
                        };
                    });
                    break;
                case 1://增加                  
                    cmb_ovenChose.Items.Add(name);
                    Tc_OvenRun t3 = new Tc_OvenRun(name);
                    Tc_OvenHistoryChart t4 = new Tc_OvenHistoryChart(name);
                    AddOvenTabpage(t3, name, tc_ovenProcessList);
                    AddOvenTabpage(t4, name, tc_ovenHistoryList);
                    t3.oven.technicsOverAction -= () => {

                        if (t4.InvokeRequired)
                        {
                            t4.Invoke(new Action(() => { t4.LoadPage(); }));
                        }
                        else
                        {
                            t4.LoadPage();
                        }
                    };
                    break;
                case 2://删除
                    cmb_ovenChose.Items.Remove(name);
                    DeleteOvenTabpage(name, tc_ovenProcessList);
                    DeleteOvenTabpage(name, tc_ovenHistoryList);
                    break;
                case 3://载入
                    List<Control> temp0 = new List<Control>();
                    tc_ovenProcessList.Controls.OfType<TabPage>().ToList().ForEach(t => temp0.Add(t.Controls[0]));
                    Tc_OvenRun temp = (Tc_OvenRun)temp0.FirstOrDefault(f => f.Name.Equals("tpg_" + name));
                    temp.oven.OpenFormula(temp.tbox_OvenFomula);
                    break;
                default: break;
            }

        }
        /// <summary>
        /// 更改烘箱前需要检查烘箱运行状态
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private bool CheckOvenState(string name)
        {
            if (tc_ovenProcessList.Controls.Count > 0)
            {
                // tc_ovenProcessList.TabPages
                TabPage tp = tc_ovenProcessList.Controls.OfType<TabPage>().FirstOrDefault(f => f.Name == "tp_" + name);
                Tc_OvenRun v = tp?.Controls[0] as Tc_OvenRun;
                return v.oven.OvenState ? false : true;
            }
            else
            { return true; }
        }
        /// <summary>
        /// 添加烘箱运行页面，根据烘箱的数量和信息增加相应界面
        /// </summary>
        /// <param name="u"></param>
        /// <param name="name"></param>
        private void AddOvenTabpage(UserControl u, string name, TabControl tcParent)
        {
            TabPage addTabPage = new TabPage();
            addTabPage.Text = name;
            addTabPage.Name = "tp_" + name;
            tcParent.Controls.Add(addTabPage);//母菜单先添加tabpage
            addTabPage.Controls.Add(u);//tabpage再添加控件
        }
        /// <summary>
        /// 删除烘箱后去除相应页面
        /// </summary>
        /// <param name="name"></param>
        /// <param name="tcParent"></param>
        private void DeleteOvenTabpage(string name, TabControl tcParent)
        {
            IEnumerable<TabPage> temptab = tcParent.Controls.OfType<TabPage>();
            var v = temptab.FirstOrDefault(f => f.Name.SplitLast("_").Equals(name));
            tcParent.Controls.Remove(v);
        }

        private void dgv_ovenAndFormula_SelectionChanged(object sender, EventArgs e)
        {
            if (dgv_ovenAndFormula.SelectedRows.Count == 0) return;

            OpenFormula(dgv_ovenAndFormula.SelectedRows[0].Cells[4].Value.ToString());
            tbox_formulaName.Text = dgv_ovenAndFormula.SelectedRows[0].Cells[2].Value.ToString().SplitFirst(".");
            cmb_ovenChose.Text = dgv_ovenAndFormula.SelectedRows[0].Cells[1].Value.ToString();
        }

        private void btn_createFormula_Click(object sender, EventArgs e)
        {
            tv_ovenTechnologicalProcess.Nodes.Clear();
        }

    }
}
